﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Text.RegularExpressions;
using App_Code.Helpers;
using PluginDB;

namespace App_Code.SiteParsers
{
    /// <summary>
    /// Summary description for MyVodParser
    /// </summary>
    public class MyVodParser : BaseScanner
    {
        private const string SERIES_DEFAULT_URL = "http://www.myvod.tv/category/%D7%A1%D7%93%D7%A8%D7%95%D7%AA/";
        private const string MOVIES_DEFAULT_URL = "http://www.myvod.tv/category/%D7%A1%D7%A8%D7%98%D7%99%D7%9D-%D7%9C%D7%A6%D7%A4%D7%99%D7%99%D7%94-%D7%99%D7%A9%D7%99%D7%A8%D7%94-2/";
        //private const string DEFAULT_URL = "http://www.myvod.tv/";

        public MyVodParser()
        {
            this.Name = "MyVod.tv";           
        }

        #region Private Methods
        private void GetMovies(string url, string moviesTypeName)
        {
            string page;
            try
            {
                page = Utils.GetPage(url, Encoding.UTF8);
            }
            catch (Exception)
            {
                page = Utils.GetPage(url, Encoding.UTF8);
            }

            const string moviesContainerExpression =
                "<div class=\"window\">.*?><a href=\"(.+?)\".*?title=\"(.+?)\".*?><img src=\"(.+?)\".*?/>";
            var exp = new Regex(moviesContainerExpression, RegexOptions.Singleline);
            var matches = exp.Matches(page);
            foreach (Match match in matches)
            {
                var moviePageLink = match.Groups[1].Value;
                var movieTitle = match.Groups[2].Value;

                if (IsVideoExists(moviePageLink))
                    continue;

                var video = FillMovieInfo(movieTitle, moviePageLink, moviesTypeName);

                AddVideoToDB(video);
            }
        }

        private PluginVideoInfo FillMovieInfo(string movieName, string moviePageLink, string moviesTypeName)
        {
            var pageContent = Utils.GetPage(moviePageLink, Encoding.UTF8);

            #region Get Plot and Image
            string plot, imageUrl;
            GetPlotAndImage(pageContent, out plot, out imageUrl);
            //video.Plot = plot;
            #endregion

            var video = new PluginVideoInfo
                            {
                                VideoName = movieName,
                                PluginUrl = moviePageLink,
                                SiteName = this.Name,
                                Categories = GetCategoriesNames(pageContent),
                                ImageUrl = imageUrl
                            };

            #region Get Links
            var links = Utils.GetMovieLinks(pageContent);
            foreach (var link in links)
            {
                video.Links.Add(new PluginVideoInfo.Link
                                    {
                                        LinkURL = link,
                                        SourceName = GetLinkSource(link)
                                    });
            }
            return video;
            #endregion
        }

        private void GetPlotAndImage(string pageContent, out string plot, out string image)
        {
            try
            {
                const string moviePlotExpression = "<div id=\"related\">(.+?)<a href";
                var matches = Regex.Matches(pageContent, moviePlotExpression, RegexOptions.Singleline);
                foreach (Match match in matches)
                {
                    const string exp = "<img src=\"(.+?)\".*?/>(.+?)[a href][<ofer>]";
                    var match1 = Regex.Match(match.Groups[1].Value + "<ofer>", exp, RegexOptions.Singleline);
                    if (match1.Success)
                    {
                        image = match1.Groups[1].Value.Trim();
                        plot = match1.Groups[2].Value.Trim();
                        return;
                    }
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception in GetPlotAndImage: {0}", ex.Message);
            }
            plot = string.Empty;
            image = string.Empty;
        }

        private List<string> GetCategoriesNames(string pageContent)
        {
            var categoriesList = new List<string>();
            const string expression = "<h5>עוד באותה קטגוריה:(.*?)</h5>";
            var match = Regex.Match(pageContent, expression, RegexOptions.Singleline);
            if (match.Success)
            {
                var cleanResult = match.Groups[1].Value.
                                    Replace("\r", string.Empty).
                                    Replace("\n", string.Empty).
                                    Replace(",", ";").Trim();
                var categories = cleanResult.Split(new[] {";"}, StringSplitOptions.RemoveEmptyEntries);
                categoriesList.AddRange(categories.Select(category => category.Trim()));
            }

            return categoriesList;
        }

        private string GetLinkSource(string link)
        {
            const string expression = @"^([a-zA-Z]+:\/\/)?([^\/]+)\/.*?$";
            var match = Regex.Match(link, expression, RegexOptions.Singleline);
            if (match.Success)
            {
                var list = match.Groups[2].Value.Split('.');
                if (list[0] == "www")
                    return list[1];
                return list[0];

            }
            return string.Empty;
        }

        public string GetNextPageLink(string pageContent)
        {
            try
            {
                const string moviePlotExpression = "class=\"wp-pagenavi\">.*?<span class=\"current\">.*?</span><a href=\"(.+?)\".*?>.*?</div>";
                var exp = new Regex(moviePlotExpression, RegexOptions.Singleline);
                var match = exp.Match(pageContent);
                if (match.Success)
                {
                    return match.Groups[1].Value.Trim();
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Excpetion in GetNextPageLink: {0}", ex.Message);
            }

            return string.Empty;
        }

        public int GetLastPageLink(string baseUrl)
        {
            try
            {
                var url = string.Format("{0}page/{1}", baseUrl, 1);
                var pageContent = Utils.GetPage(Utils.LoopDecodeUrl(url), Encoding.UTF8);

                const string moviePlotExpression = "class=\"wp-pagenavi\">.*?<span class=\"current\">.*?</span><a href.*?</a><a href.*?</a>.*?<a href=\"(.+?)\".*?>.*?</div>";
                var exp = new Regex(moviePlotExpression, RegexOptions.Singleline);
                var match = exp.Match(pageContent);
                if (match.Success)
                {
                    var urlFormat = string.Format("{0}page/", baseUrl);
                    var pageNumber = match.Groups[1].Value.Trim().Replace(urlFormat, string.Empty);
                    return int.Parse(pageNumber);
                }
            }
            catch(Exception ex)
            {
                Console.WriteLine("Exception in GetLastPageLink: {0}", ex.Message);
            }

            return 0;
        }
        #endregion
        
        #region Implementation of ISiteScanner
        public override int GetMoviesLastPageNumber()
        {
            return GetLastPageLink(MOVIES_DEFAULT_URL);
        }

        public override void ScanForMovies(int pagesToScan)
        {
            var lastPageNumber = GetMoviesLastPageNumber();
            pagesToScan = (pagesToScan == 0 || pagesToScan > lastPageNumber) ? lastPageNumber : pagesToScan;

            for (var i = pagesToScan; i > 0; i--)
            {
                var url = string.Format("{0}page/{1}", MOVIES_DEFAULT_URL, i);
                this.GetMovies(url, Common.MOVIES_NAME);
            }
        }

        public override int GetSeriesLastPageNumber()
        {
            return GetLastPageLink(SERIES_DEFAULT_URL);
        }

        public override void ScanForSeries(int pagesToScan)
        {
            var lastPageNumber = GetSeriesLastPageNumber();
            pagesToScan = (pagesToScan == 0 || pagesToScan > lastPageNumber) ? lastPageNumber : pagesToScan;

            for (var i = pagesToScan; i > 0; i--)
            {
                var url = string.Format("{0}page/{1}", SERIES_DEFAULT_URL, i);
                this.GetMovies(url, Common.SERIES_NAME);
            }
        }
        #endregion              
    }
}